<?php

namespace app\api\controller\shop;



use app\admin\model\usermanage\Users;
use app\admin\model\usermanage\UsersWage;
use app\api\model\Address;
use app\api\model\PvLog;
use app\api\model\Register;
use app\api\model\shop\Carts;
use app\api\model\shop\Order as OrderModel;
use app\api\model\shop\OrderAction;
use app\api\model\shop\OrderGoods;

use app\common\controller\Api;
use fast\Security;
use think\Db;


/**
 * 订单接口
 */
class Order extends Api
{
    protected $noNeedLogin = ['epay'];
    protected $noNeedRight = ['*'];



    //计算邮费，判断商品
    public function carts()
    {
        $cart_ids = $this->request->post('ids');
        $address_id = $this->request->post('address_id/d'); //地址id
        if (empty($cart_ids)) {
            $this->error('参数缺失');
        }
        $user_coupon_id = $this->request->post('user_coupon_id/d'); //优惠券
        $integral = input('integral',0);
        $address = Address::get($address_id);
        $orderInfo = [
            'order_sn'    => '',
            'amount'      => 0, //订单金额（包含运费）
            'shippingfee' => 0, //运费
            'goodsprice'  => 0 //商品金额
        ];
        $user = Users::where(['id'=>$this->auth->id])->field('id,account,price,integral,money')->find();
        if ($integral>$user->integral){
            $this->error('用户积分不足');
        }
        $goodsList = [];
        $area_id = !empty($address) ? $address->district_id : 0;
        try {
            list($orderItem, $goodsList) = OrderModel::computeCarts($orderInfo, $cart_ids, $this->auth->id, $area_id, $user_coupon_id,$integral);
            if (empty($goodsList)) {
                throw new \Exception("未找到商品");
            }
        } catch (\Exception $e) {
            $this->error($e->getMessage());
        }
        foreach ($goodsList as $item) {
            $item->category_id = $item->goods->category_id;
            $item->brand_id = $item->goods->brand_id;
            $item->goods->visible(explode(',', 'id,title,image,price,marketprice,integral'));
        }
        //获取我的可以使用的优惠券
        $goods_ids = array_column($goodsList, 'goods_id');
        $category_ids = array_column($goodsList, 'category_id');
        $brand_ids = array_column($goodsList, 'brand_id');

        $this->success('获取成功', [
            'goods_list'       => $goodsList,
            'order_info'       => $orderInfo,
            'user'             => $user
            //'couponTotalPrice' => floatval(!isset($config['shippingfeecoupon']) || $config['shippingfeecoupon'] == 0 ? $orderInfo['goodsprice'] : $orderInfo['amount'])
        ]);
    }

    //提交订单
    public function add()
    {
        $cart_ids = $this->request->post('ids');
        $address_id = $this->request->post('address_id/d'); //地址id
        $user_coupon_id = $this->request->post('user_coupon_id/d'); //地址id
        $memo = $this->request->post('memo');
        $integral = input('integral',0);
        if (empty($address_id)) {
            $this->error('请选择地址');
        }
        if (empty($cart_ids)) {
            $this->error('请选择商品');
        }
        //为购物车id
        //校验购物车id 合法
        $row = (new Carts)->where('id', 'IN', $cart_ids)->where('user_id', '<>', $this->auth->id)->find();
        if ($row) {
            $this->error('存在不合法购物车数据');
        }
        $order = null;
        try {
            $order = OrderModel::createOrder($address_id, $this->auth->id, $cart_ids, $user_coupon_id, $memo,$integral);
        } catch (\Exception $e) {
            $this->error($e->getMessage());
        }
        $this->success('下单成功！', $order);
    }

    //订单详情
    public function detail()
    {
        $order_sn = $this->request->param('order_sn');
        if (empty($order_sn)) {
            $this->error('参数缺失');
        }
        $order = OrderModel::getDetail($order_sn, $this->auth->id);
        if (empty($order)) {
            $this->error('未找到订单');
        }
        $order->append(['status_text']);
        $order->hidden(explode(',', 'method,transactionid,updatetime,deletetime'));
        $order->expiretime = $order->expiretime - time();
        $this->success('', $order);
    }

    //订单列表
    public function index()
    {
        $param = $this->request->param();
        $param['user_id'] = $this->auth->id;
        $list = OrderModel::tableList($param);

        foreach ($list as $k=>$v){
            $order_pv_send_sum = PvLog::find()->where([
                'user_id'=>$v['user_id'],
                'order_id'=>$v['id'],
                'type'=>2,
                'pv_type'=>2,
            ])->sum('pv');
            $list[$k]['surplus_pv'] = bcsub($v['pv'],$order_pv_send_sum,1);
        }

        foreach ($list as $item) {
            $item->append(['status_text']);
            $field = 'id,order_sn,amount,expressno,expressname,saleamount,shippingfee,paystate,orderstate,shippingstate,order_goods,status,status_text,surplus_pv';
            $item->visible(explode(',', $field));
        }

        $this->success('获取成功', $list);
    }

    //取消订单
    public function cancel()
    {
        $order_sn = $this->request->post('order_sn');
        if (!$order_sn) {
            $this->error('参数错误');
        }
        $order = OrderModel::getByOrderSn($order_sn);
        if (empty($order)) {
            $this->error('订单不存在');
        }
        if ($order->user_id != $this->auth->id) {
            $this->error('不能越权操作');
        }
        if ($order->status == 'hidden') {
            $this->error('订单已失效！');
        }
        //可以取消
        if (!$order->paystate && !$order->orderstate) {
            // 启动事务
            Db::startTrans();
            try {
                $order->orderstate = 1;
                $order->canceltime = time();
                $order->save();
                foreach ($order->order_goods as $item) {
                    $sku = $item->sku;
                    $goods = $item->goods;
                    //商品库存恢复
                    if ($sku) {
                        $sku->setInc('stocks', $item->nums);
                    }
                    if ($goods) {
                        $goods->setInc('stocks', $item->nums);
                    }
                }

                // 用户积分恢复
                $integral = $order->integralprice;
                if ($integral > 0){
                    $user = Users::get(['id' => $order->user_id]);

                    $user->integral += $integral;
                    $register = new Register();
                    $register->user_id = $user->id;
                    $register->register_time = '..';
                    $register->continuation = 0;
                    $register->setAttr('type',6);
                    $register->integral = $integral;
                    $register->order_id = $order->id;
                    $register->save();
                    $user->save();

                }


                // 提交事务
                Db::commit();
            } catch (\Exception $e) {
                // 回滚事务
                Db::rollback();
                $this->error('订单取消失败');
            }
            //记录操作
            OrderAction::push($order->order_sn, '系统', '订单取消成功');
            $this->success('订单取消成功！', $order['status']);
        } else {
            $this->error('订单不允许取消');
        }
    }

    //订单支付
    public function pay()
    {
        $order_sn = $this->request->post('order_sn');
        $paytype = $this->request->post('paytype','wechat');
        $method = $this->request->post('method','miniapp');
        $appid = $this->request->post('appid'); //为APP的应用id
        $returnurl = $this->request->post('returnurl', '', 'trim');
        $user = Users::get($this->auth->id);

        $openid = '';
        if ($method=='miniapp'){
            $openid = $user->wechat_open_id;
        }
        //非H5 支付,非余额
        /*if (in_array($method, ['miniapp', 'mp']) && $paytype == 'wechat') {
            $info = get_addon_info('third');
            if (!$info || !$info['state']) {
                $this->error("请在后台安装第三方登录插件");
            }
            $third = Third::where('platform', 'wechat')
                ->where('apptype', $method)
                ->where('user_id', $this->auth->id)
                ->find();

            if (!$third) {
                $this->error("未找到微信授权的用户信息", 'bind');
            }
            $openid = $third['openid'];
        }*/
        $orderInfo = OrderModel::getByOrderSn($order_sn);
        if (!$orderInfo) {
            $this->error("未找到指定的订单");
        }
        if ($orderInfo['paystate']) {
            $this->error("订单已经支付，请勿重复支付");
        }
        //订单过期
        if (!$orderInfo['orderstate'] && time() > $orderInfo['expiretime']) {
            // 启动事务
            Db::startTrans();
            try {
                $orderInfo->save(['orderstate' => 2]);
                //库存恢复
                OrderGoods::setGoodsStocksInc($orderInfo->order_sn);

                // 提交事务
                Db::commit();
            } catch (\Exception $e) {
                // 回滚事务
                Db::rollback();
            }
            $this->error("订单已失效");
        }
        $response = null;
        try {
            $response = OrderModel::pay($order_sn, $this->auth->id, $paytype, $method, $openid, '', $returnurl);
        } catch (\Exception $e) {
            $this->error($e->getMessage());
        }
        $this->success("请求成功", $response);
    }

    //订单余额支付
    public function balancePay()
    {

        $order_sn = input('order_sn','');
        $pay_pwd = input('pay_pwd','');
        if (empty($pay_pwd))$this->error('请输入支付密码');

        $order = OrderModel::get(['order_sn'=>$order_sn,'user_id'=>$this->auth->id]);
        if (!$order) {
            $this->error('订单不存在！');
        }
        if ($order->paystate) {
            $this->error('订单已支付！');
        }
        if ($order->orderstate) {
            $this->error('订单已失效！');
        }
        //支付金额为0，无需支付
        if ($order->saleamount == 0) {
            $this->error('无需支付！');
        }

        $user = Users::get(['id' => $this->auth->id]);
        if (empty($user->pay_pwd)){
            $this->error('请先设置支付密码');
        }
        $security_model = new Security();

        if (!$security_model->validatePassword($pay_pwd, $user->pay_pwd)) {
            $this->error('支付密码错误');
        }

        if (!$user) {
            $this->error('网络异常');
        }

        if ($user->price < $order->saleamount) {
            $this->error('支付失败，余额不足');
        }


        $order->paytype = 'balance';
        $order->save();

        $res = OrderModel::settle($order['order_sn'], $order['saleamount']);
        if ($res){
            $this->success('支付成功',$res);
        } else {
            $this->error('支付失败');
        }

    }

    //确认收货
    public function takedelivery()
    {
        $order_sn = $this->request->post('order_sn');
        if (!$order_sn) {
            $this->error('参数错误');
        }
        $order = OrderModel::getByOrderSn($order_sn);
        if (empty($order)) {
            $this->error('订单不存在');
        }
        if ($order->user_id != $this->auth->id) {
            $this->error('不能越权操作');
        }
        if ($order->status == 'hidden') {
            $this->error('订单已失效！');
        }
        if ($order->paystate == 1 && !$order->orderstate && $order->shippingstate == 1) {
            $order->shippingstate = 2;
            $order->receivetime = time();
            $order->save();
            //记录操作
            OrderAction::push($order->order_sn, '系统', '订单确认收货成功');
            $this->success('确认收货成功');
        }
        $this->error('未可确认收货');
    }

    /**
     * @ DateTime 2021-06-01
     * @ 支付回调
     * @return void
     */
    public function epay()
    {
        $type = $this->request->param('type');
        $paytype = $this->request->param('paytype');
        if ($type == 'notify') {
            $pay = \addons\epay\library\Service::checkNotify($paytype);
            if (!$pay) {
                echo '签名错误';
                return;
            }
            $data = $pay->verify();
            try {
                $payamount = $paytype == 'alipay' ? $data['total_amount'] : $data['total_fee'] / 100;
                OrderModel::settle($data['out_trade_no'], $payamount, $paytype == 'alipay' ? $data['trade_no'] : $data['transaction_id']);
            } catch (\Exception $e) {
                \think\Log::write($e->getMessage(), 'epay');
            }
            echo $pay->success();
        }
        return;
    }
}